#include <stdio.h>
#include <stdlib.h>
#include <stdbool.h>
#include <unistd.h>
#include <string.h>
#include <strings.h>
#include <unistd.h>
#include <fcntl.h>
#include <pwd.h>
#include <grp.h>
#include <time.h>
#include <errno.h> // 定义了全局错误码 errno
#include <sys/types.h>
#include <sys/stat.h>
#include <sys/mman.h>
#include <sys/sysmacros.h>

char type(mode_t mode){
    if(S_ISREG(mode))return '-';
    if(S_ISDIR(mode))return 'd';
    if(S_ISCHR(mode))return 'c';
    if(S_ISBLK(mode))return 'b';
    if(S_ISFIFO(mode))return 'f';
    if(S_ISLNK(mode))return 'l';
    if(S_ISSOCK(mode))return 's';
}

char *permision(mode_t mode){
    static char buf[10];
    char pm[] = {'r', 'w', 'x'};
    for(int i = 0; i < 9; i++)
        buf[i] = mode & (0400>>i) ? pm[i % 3] : '-';
    return buf;
}

int main(int argc, char **argv){
    // 获取指定文件的属性信息
    struct stat info;
    stat(argv[1], &info); 

    //打印文件类型
    printf("%c", type(info.st_mode));

    //打印文件权限
    printf("%s ", permision(info.st_mode));

    //打印文件别名数目
    printf("%ld ", info.st_nlink);

    //打印文件所有者，所属组
    printf("%s %s ", getpwuid(info.st_uid)->pw_name, getgrgid(info.st_gid)->gr_name);

    //打印文件所属设备设备号或文件字节大小
    if(S_ISBLK(info.st_mode) || S_ISCHR(info.st_mode))
    printf("%u %u ", major(info.st_rdev), minor(info.st_rdev));
    else printf("%ld ", info.st_size);

    //打印文件最近访问时间
    char file_atime[20];
    strncpy(file_atime, ctime(&info.st_atime), 20);
    printf("%s ", file_atime);

    //打印文件的名字
    printf("%s\n", argv[1]);
}